<template>
  <div class="map-container">
    <div id="map" ref="mapContainer"></div>
    <div class="control-panel">
      <button @click="toggleDrawMode">{{ isDrawMode ? '停止绘制' : '开始绘制' }}</button>
      <button @click="clearRectangles">清除所有</button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import mapboxgl from 'mapbox-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import { setMapInstance } from '@/utils/mapUtils'

const mapContainer = ref<HTMLElement | null>(null)
let map: mapboxgl.Map | null = null
const isDrawMode = ref(false)
const isDrawing = ref(false)
const startPoint = ref<[number, number] | null>(null)
const currentRectangle = ref<GeoJSON.Feature | null>(null)
const rectangleCollection = ref<GeoJSON.FeatureCollection>({
  type: 'FeatureCollection',
  features: []
})
const rectangleLayerId = 'rectangle-layer'
const tempRectangleSourceId = 'temp-rectangle-source'
const tempRectangleLayerId = 'temp-rectangle-layer'

const initMap = () => {
  if (!mapContainer.value) return
  
  mapboxgl.accessToken = import.meta.env.VITE_APP_MAP_TOKEN
  
  map = new mapboxgl.Map({
    container: mapContainer.value,
    style: 'mapbox://styles/mapbox/streets-v12',
    center: [116.397428, 39.90923],
    zoom: 12
  })

  map.on('load', () => {
    // Add source for completed rectangles
    map?.addSource('rectangle-source', {
      type: 'geojson',
      data: rectangleCollection.value
    })

    // Add layer for completed rectangles
    map?.addLayer({
      id: rectangleLayerId,
      type: 'fill',
      source: 'rectangle-source',
      paint: {
        'fill-color': '#4e9af5',
        'fill-opacity': 0.5,
        'fill-outline-color': '#0066cc'
      }
    })

    // Add layer for rectangle outline
    map?.addLayer({
      id: 'rectangle-outline',
      type: 'line',
      source: 'rectangle-source',
      paint: {
        'line-color': '#0066cc',
        'line-width': 2
      }
    })

    // Add source for the temp rectangle being drawn
    map?.addSource(tempRectangleSourceId, {
      type: 'geojson',
      data: {
        type: 'Feature',
        geometry: {
          type: 'Polygon',
          coordinates: [[
            [0, 0],
            [0, 0],
            [0, 0],
            [0, 0],
            [0, 0]
          ]]
        },
        properties: {}
      }
    })

    // Add layer for the temp rectangle
    map?.addLayer({
      id: tempRectangleLayerId,
      type: 'fill',
      source: tempRectangleSourceId,
      paint: {
        'fill-color': '#4e9af5',
        'fill-opacity': 0.3,
        'fill-outline-color': '#0066cc'
      }
    })

    // Add temp rectangle outline layer
    map?.addLayer({
      id: 'temp-rectangle-outline',
      type: 'line',
      source: tempRectangleSourceId,
      paint: {
        'line-color': '#0066cc',
        'line-width': 2,
        'line-dasharray': [2, 2]
      }
    })

    // Event handlers for drawing
    setupDrawingEventHandlers()
  })

  setMapInstance(map)
}

const setupDrawingEventHandlers = () => {
  if (!map) return

  // First click - start drawing
  map.on('click', (e) => {
    if (!isDrawMode.value) return
    
    // If not drawing yet, start a new rectangle
    if (!isDrawing.value) {
      isDrawing.value = true
      startPoint.value = [e.lngLat.lng, e.lngLat.lat]
      
      // Initialize the temp rectangle
      updateTempRectangle(startPoint.value, startPoint.value)
    } 
    // If already drawing, complete the rectangle
    else if (startPoint.value) {
      const endPoint: [number, number] = [e.lngLat.lng, e.lngLat.lat]
      
      // Complete the rectangle
      completeRectangle(startPoint.value, endPoint)
      
      // Reset drawing state
      isDrawing.value = false
      startPoint.value = null
      
      // Clear temp rectangle
      updateTempRectangle([0, 0], [0, 0])
    }
  })

  // Mouse move - update rectangle while in drawing mode, but after first click
  map.on('mousemove', (e) => {
    // Only update if we're in drawing mode AND we've made the first click
    if (!isDrawMode.value || !isDrawing.value || !startPoint.value) return
    
    // Update the rectangle as mouse moves (without needing to hold the button)
    updateTempRectangle(startPoint.value, [e.lngLat.lng, e.lngLat.lat])
  })
}

const updateTempRectangle = (start: [number, number], end: [number, number]) => {
  if (!map) return
  
  // Create rectangle coordinates from start and end points
  const coords = createRectangleCoordinates(start, end)
  
  // Update the temporary rectangle
  const geojsonSource = map.getSource(tempRectangleSourceId) as mapboxgl.GeoJSONSource
  if (geojsonSource) {
    geojsonSource.setData({
      type: 'Feature',
      geometry: {
        type: 'Polygon',
        coordinates: [coords]
      },
      properties: {}
    })
  }
}

const completeRectangle = (start: [number, number], end: [number, number]) => {
  if (!map) return
  
  // Create rectangle coordinates from start and end points
  const coords = createRectangleCoordinates(start, end)
  
  // Skip if rectangle is too small
  if (Math.abs(start[0] - end[0]) < 0.0001 && Math.abs(start[1] - end[1]) < 0.0001) {
    return
  }
  
  // Create a new rectangle feature
  const newRectangle: GeoJSON.Feature = {
    type: 'Feature',
    geometry: {
      type: 'Polygon',
      coordinates: [coords]
    },
    properties: {
      id: Date.now().toString()
    }
  }
  
  // Add to collection
  rectangleCollection.value.features.push(newRectangle)
  
  // Update the map source
  const source = map.getSource('rectangle-source') as mapboxgl.GeoJSONSource
  if (source) {
    source.setData(rectangleCollection.value)
  }
}

const createRectangleCoordinates = (start: [number, number], end: [number, number]): [number, number][] => {
  return [
    [start[0], start[1]],
    [end[0], start[1]],
    [end[0], end[1]],
    [start[0], end[1]],
    [start[0], start[1]] // Close the polygon
  ]
}

const toggleDrawMode = () => {
  isDrawMode.value = !isDrawMode.value
  
  if (!isDrawMode.value) {
    // Reset drawing state when exiting draw mode
    isDrawing.value = false
    startPoint.value = null
    updateTempRectangle([0, 0], [0, 0])
  }
  
  // Change cursor based on draw mode
  if (map) {
    map.getCanvas().style.cursor = isDrawMode.value ? 'crosshair' : ''
  }
}

const clearRectangles = () => {
  if (!map) return
  
  // Clear all rectangles
  rectangleCollection.value.features = []
  
  // Update the map source
  const source = map.getSource('rectangle-source') as mapboxgl.GeoJSONSource
  if (source) {
    source.setData(rectangleCollection.value)
  }
}

onMounted(() => {
  initMap()
})

onUnmounted(() => {
  map?.remove()
  map = null
})
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 100vh;
  position: relative;
}

#map {
  width: 100%;
  height: 100%;
}

.control-panel {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 1;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  display: flex;
  gap: 8px;
}

button {
  padding: 8px 16px;
  background: #2c3e50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:hover {
  background: #34495e;
}
</style> 